/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.letmeshare.pedagogue.core.message.entities.module;

import java.util.List;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.letmeshare.pedagogue.core.entities.Party;
import org.letmeshare.pedagogue.core.entities.Person;
import org.letmeshare.pedagogue.core.message.entities.MailBox;
import org.letmeshare.pedagogue.core.message.entities.Message;
import org.letmeshare.pedagogue.core.module.AbstractModule;

/**
 *
 * @author abin
 */
public class MessageModule extends AbstractModule {

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public static void sendMessage(EntityManager em, Message message) {
        isNull(message, "Message Cant be null");
        checkEntityManager(em);
        message.validate();
        MailBox box = getMailBox(em, message.getSender().getUid());
        if (message.getId() == null) {
            em.persist(message);
        } else {
            // Draft Message
            boolean isDraft=box.getDraftMessages().remove(message);
           if(!isDraft){
               throw  new IllegalArgumentException("Unable to find Draft Message");
           }
        }
        box.addSendMessage(message);
        for (Party recipient : message.getRecipients()) {
            sendMessageToRecipient(em, message, recipient);
        }
        em.merge(box);
    }

    private static void sendMessageToRecipient(EntityManager em, Message message, Party recipient) {
        MailBox box = getMailBox(em, recipient.getUid());
        box.getRecivedMessages().add(message);
        em.merge(box);
    }

    private static MailBox getMailBox(EntityManager em, String uid) {
        Query q = em.createNamedQuery(MailBox.GET_USER_MAILBOX);
        q.setParameter("uid", uid);
        MailBox box = (MailBox) q.getSingleResult();
        return box;
    }
    public static List<Message> getReciviedMessages(EntityManager em,Party p,int firstPosition,int numberOfRecords){
        checkEntityManager(em);
        isNull(p, "User cant be Null");
        if(firstPosition<0||numberOfRecords<1)
            throw new IllegalArgumentException("Invalid limit");
        Query q=em.createNamedQuery(MailBox.GET_RECIVED_MESSAGES);
        q.setFirstResult(firstPosition);
        q.setMaxResults(numberOfRecords);
       return q.getResultList();
    }
    public static List<Message> getSendMessages(EntityManager em,Party p,int firstPosition,int numberOfRecords){
        checkEntityManager(em);
        isNull(p, "User cant be Null");
        if(firstPosition<0||numberOfRecords<1)
            throw new IllegalArgumentException("Invalid limit");
        Query q=em.createNamedQuery(MailBox.GET_SEND_MESSAGES);
        q.setFirstResult(firstPosition);
        q.setMaxResults(numberOfRecords);
       return q.getResultList();
    }
    public static List<Message> getDraftMessages(EntityManager em,Party p,int firstPosition,int numberOfRecords){
        checkEntityManager(em);
        isNull(p, "User cant be Null");
        if(firstPosition<0||numberOfRecords<1)
            throw new IllegalArgumentException("Invalid limit");
        Query q=em.createNamedQuery(MailBox.GET_DRAFT_MESSAGES);
        q.setFirstResult(firstPosition);
        q.setMaxResults(numberOfRecords);
       return q.getResultList();
    }
    public static  boolean deleteMessage(EntityManager em,Message message,Party party){
        boolean isDeleted=false;
        if(deleteDraftMessage(em, message, party)){
            return true;
        }else if(deleteRecivedMessage(em, message, party)){
            return true;
        }else if(deleteSendDraftMessage(em, message, party)){
            return true;
        }
        return isDeleted;
    }
    public static  boolean deleteDraftMessage(EntityManager em,Message message,Party party){
        boolean isDeleted=false;
        MailBox box=getMailBox(em, party.getUid());
        isDeleted=box.getDraftMessages().remove(message);
        if(isDeleted){
            em.remove(message);
        }
        em.merge(box);
        return isDeleted;
    }
    public static  boolean deleteSendDraftMessage(EntityManager em,Message message,Party party){
        boolean isDeleted=false;
        MailBox box=getMailBox(em, party.getUid());
        isDeleted=box.getSendMessages().remove(message);
        em.merge(box);
        return isDeleted;
    }
    public static  boolean deleteRecivedMessage(EntityManager em,Message message,Party party){
        boolean isDeleted=false;
        MailBox box=getMailBox(em, party.getUid());
        isDeleted=box.getRecivedMessages().remove(message);
        em.merge(box);
        return isDeleted;
    }
    public static void saveMessage(EntityManager em,Message message,Party party){
        checkEntityManager(em);
        isNull(message, "Message cant be null");
        isNull(party, "User cant be null");
        if(message.getSender()!=null && message.getSender()==party){
            if(message.getId()==null){
                em.persist(message);
            }else{
                em.merge(message);
            }
            MailBox box= getMailBox(em, party.getUid());
            box.addDraftMessage(message);
            em.merge(box);
        }else{
            throw  new IllegalArgumentException("Your are trying to save someone's message");
        }
    }
    //TODO need to Implement Search functionality
}
